package com.podcstr.service;

import com.podcstr.dao.CommentDao;
import com.podcstr.dao.MediaFileDao;
import com.podcstr.dao.PodcastDao;
import com.podcstr.entity.Podcast;
import com.podcstr.service.exception.ServiceException;
import org.apache.log4j.Logger;

import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author azim
 * @since 5/19/13 
 */

@Stateless
@Local(PodcastService.class)
public class PodcastServiceImpl implements PodcastService {

    private final Logger log = Logger.getLogger(PodcastServiceImpl.class.getName());

    @Inject
    private PodcastDao podcastDao;

    @Inject
    private MediaFileDao mediaFileDao;

    @Inject
    private CommentDao commentDao;

    @Override
    public void add(Podcast podcast) throws ServiceException {

        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        Set violations = validator.validate(podcast);
        if (violations.size() > 0) {

            throw new ServiceException(violations);
        }

        Podcast existingPodcast = podcastDao.findByPodcastName(podcast.getName());
        if (existingPodcast != null) {

            throw new ServiceException("Duplicate Podcast. This podcast already exists.");
        }
        try {

            mediaFileDao.add(podcast.getAlbumArt());
            mediaFileDao.add(podcast.getAudio());
            podcastDao.add(podcast);
            log.info(new Date() + " : Added a new podcast with name : " + podcast.getName());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public List<Podcast> findAll() {

        log.info(new Date() + " : Returning the list of podcasts.");

        List<Podcast> podcasts = podcastDao.findAll();
        for (Podcast podcast : podcasts) {
            podcast.setRating(commentDao.calculteRatingOfPodcast(podcast.getId()));
        }

        return podcasts;
    }

    @Override
    public void delete(long podcastId) {

        podcastDao.delete(podcastId);
        log.info(new Date() + " : Deleting a podcast with id : " + podcastId + ".");
    }

    @Override
    public void toggleAccess(long podcastId) {

        podcastDao.toggleAccess(podcastId);
        log.info(new Date() + " : Toggling podcast with id : " + podcastId + " accessable value.");
    }

    @Override
    public void update(Podcast podcast) {

        podcastDao.update(podcast);
        log.info(new Date() + " : Updated the podcast with id : " + podcast.getId() + ".");
    }

    @Override
    public Podcast findByPodcastName(String podcastName) {

        log.info(new Date() + " Returning the podcast with name : " + podcastName + ".");
        return podcastDao.findByPodcastName(podcastName);
    }

    @Override
    public List<Podcast> findByUserId(long userId) {

        log.info(new Date() + " : Returning the list of podcasts by user with id : " + userId + ".");

        List<Podcast> podcasts = podcastDao.findByUserId(userId);
        for (Podcast podcast : podcasts) {
            podcast.setRating(commentDao.calculteRatingOfPodcast(podcast.getId()));
        }

        return podcasts;
    }

    @Override
    public List<Podcast> findByTags(String tag) {

        log.info(new Date() + " : Returning the list of podcasts with tag : " + tag + ".");

        List<Podcast> podcasts = podcastDao.findByTags(tag);
        for (Podcast podcast : podcasts) {
            podcast.setRating(commentDao.calculteRatingOfPodcast(podcast.getId()));
        }

        return podcasts;
    }

    @Override
    public List<Podcast> findByCategoryId(long categoryId) {

        log.info(new Date() + " : Returning the list of podcasts of category with id : " + categoryId + ".");
        List<Podcast> podcasts = podcastDao.findByCategoryId(categoryId);
        for (Podcast podcast : podcasts) {
            podcast.setRating(commentDao.calculteRatingOfPodcast(podcast.getId()));
        }

        return podcasts;
    }

    @Override
    public long countPodcastByUserId(long userId) {

        log.info(new Date() + " : Returning total no. of podcast by user with id : " + userId);
        return podcastDao.countPodcastByUserId(userId);
    }

    @Override
    public List<Podcast> searchPodcast(String word) {

        log.info(new Date() + " : Returning the list of podcasts with search string : " + word + ".");
        List<Podcast> podcasts = podcastDao.searchPodcast(word);
        if( podcasts.size() != 0)
        {
            for (Podcast podcast : podcasts) {
                podcast.setRating(commentDao.calculteRatingOfPodcast(podcast.getId()));
            }
        }

        return podcasts;
    }
}
